﻿using System;
using System.Collections;
using System.Collections.Generic;
using Gameplay.PVE;
using Gameplay.PVE.Survivor;
using OWL.Rendering.HRP;
using UnityEngine;
using UnityEngine.AI;
using Yoozoo.HRP.Runtime;

public class MapInteractableData : MonoBehaviour
{
    public int id;
    public int regionId;
    public float totalDuration;
    public int stage;
    public GameObject hintObject;
    public List<BattleMapInteractableEvent> events;
    //是否锁死玩家操作
    public bool isLockUnit = true;
    public EBattleInteractableType interactableType = EBattleInteractableType.Single;
    public int repeatTimes;
    public bool forbidInBattle = false;
    //离开区域是否有效 (默认有效)
    public bool outRegionValid = true;
    public void PlayAnimation(string animationName)
    {
        var animator = GetComponent<Animator>();
        if (animator != null)
        {
            animator.SetTrigger(animationName);
        }
    }

    //运行时数据
    private bool finished = false;
    private float startTime;
    private bool valid;
    private int times;

    public void Init()
    {
        times = 0;
        finished = false;
        startTime = -1;
        interactableRegion = StageManager.Instance.GetRegion(regionId);
        interactableState.Clear();
        interactableParams.Clear();
        for (int i = 0; i < events.Count; i++)
        {
            interactableState.Add(0);
            interactableParams.Add(0);
        }
    }

    private void ResetState()
    {
        for (int i = 0; i < interactableState.Count; i++)
        {
            interactableState[i] = 0;
        }

        for (int i = 0; i < interactableParams.Count; i++)
        {
            interactableParams[i] = 0;
        }
    }

    public void OnStageStart(int stageId)
    {
        if (finished)
        {
            return;
        }
        if (stageId >= stage)
        {
            //BattleDebug.LogError("交互物启动 " + id + " 阶段" + stageId);
            valid = true;
            if (hintObject != null)
            {
                hintObject.SetActive(true);
            }
        }
    }

    private BattleMapRegion interactableRegion;
    private List<int> interactableState = new List<int>();
    private List<float> interactableParams = new List<float>();

    public bool Finished => finished;

    private bool forceTrigger = false;
    
    public void Trigger()
    {
        valid = true;
        finished = false;
        forceTrigger = true;
        Init();
    }

    public bool UpdateInteractable()
    {
        if (!SurvivorManager.isInteractableActive)
        {
            return false;
        }
        if (!valid)
        {
            return false;
        }
        if (finished)
        {
            return false;
        }

        var team = StageManager.Instance.TeamGroup;
        var teamPosition = team.Position;
        if (startTime < 0)
        {
            if (forbidInBattle)
            {
                if (team.IsInBattle())
                {
                    return false;
                }
            }
            //检查是否可以开始
            var isIn = BattleHelper.IsInRegion(teamPosition,interactableRegion);
            if (isIn || forceTrigger)
            {
                if (isLockUnit)
                {
                    team.StartInteract();
                }
                startTime = TimeManager.time;
                if (hintObject != null)
                {
                    hintObject.SetActive(false);
                }
            }
        }
        else
        {
            if (!isLockUnit)
            {
                var isIn = BattleHelper.IsInRegion(teamPosition, interactableRegion);
                if (!isIn && !outRegionValid)
                {
                    startTime = 0;
                    ResetState();
                    return false;
                }
            }
            for (int i = 0; i < events.Count; i++)
            {
                CheckEvent(events[i],i);
            }
            if (TimeManager.time > startTime + totalDuration)
            {
                if (isLockUnit)
                {
                    StageManager.Instance.TeamGroup.StopInteract();
                }

                if (interactableType == EBattleInteractableType.Single)
                {
                    finished = true;
                    forceTrigger = false;
                    return true;
                }
                else if (interactableType == EBattleInteractableType.Repeat)
                {
                    times++;
                    if (times >= repeatTimes)
                    {
                        finished = true;
                        forceTrigger = false;
                        return true;
                    }
                    finished = false;
                    forceTrigger = false;
                    startTime = TimeManager.time;
                    ResetState();
                    return false;
                }
            }
        }
        return false;
    }

    private void CheckEvent(BattleMapInteractableEvent evt,int i)
    {
        var team = StageManager.Instance.TeamGroup;
        var needStart = TimeManager.time - startTime >= evt.startTime && interactableState[i] == 0;
        var needEnd = TimeManager.time - startTime >= evt.endTime && interactableState[i] == 1;
        if (needStart)
        {
            interactableState[i] = 1;
        }
        else if (needEnd)
        {
            interactableState[i] = 2;
        }
        if (evt.eventType == EBattleInteractableEvent.PlayerAnimation)
        {
            int index = 0;
            int.TryParse(evt.param2, out index);
            if (needStart)
            {
                //BattleDebug.LogError("开始播放人物动作" + evt.param + index);
                team.PlayAnimationInteractable(evt.param,index);
            }
            else if (needEnd)
            {
                //BattleDebug.LogError("结束播放人物动作" + evt.param + " " + index);
                team.PlayAnimationInteractable("Idle",index);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.SelfAnimation)
        {
            if (needStart)
            {
                //BattleDebug.LogError("开始播放交互物动作");
                PlayAnimation(evt.param);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.PlayerMoveTo)
        {
            int index = 0;
            int.TryParse(evt.param2, out index);
            if (needStart)
            {
                if (int.TryParse(evt.param, out var id))
                {
                    //BattleDebug.LogError("开始前往" + id);
                    var point = StageManager.Instance.GetMapPoint(id);
                    var forward = StageManager.Instance.GetMapPointForward(id);
                    team.MoveToInteractable(point,forward,index);
                }
            }
            else if (needEnd)
            {
                team.StopMoveToInteractable(index);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.CameraShake)
        {
            if (needStart)
            {
                
                float.TryParse(evt.param, out var time);
                float.TryParse(evt.param2, out var intensity);
                //BattleDebug.LogError("开始摄像机震动 " + time);
                CameraManager.Instance.Shake(time);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.FlyText)
        {
            var time = TimeManager.time - startTime;
            if (time <= evt.endTime && time >= evt.startTime)
            {
                if (interactableParams[i] == 0 || TimeManager.time > interactableParams[i])
                {
                    //BattleDebug.LogError("飘字 " + evt.param);
                    int.TryParse(evt.param, out var flyTextType);
                    float.TryParse(evt.param2, out var flyTextInterval);
                    int.TryParse(evt.param3, out var pointIndex);
                    var position = StageManager.Instance.GetMapPoint(pointIndex);
                    FlyTextManager.Instance.ShowFlyText((EFlyTextType)flyTextType,position,BattleConfigManager.GetLangText(evt.param4));
                    interactableParams[i] = TimeManager.time + flyTextInterval;
                }
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.TriggerEvent)
        {
            if (needStart)
            {
                //BattleDebug.LogError("触发事件 " + evt.param);
                if (int.TryParse(evt.param, out var eventId))
                {
                    var config = BattleConfigManager.Instance.GetStageEventConfig(eventId);
                    BattleEventManager.Instance.TriggerEvent(config,null,this);
                }
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.TimeScale)
        {
            if (needStart)
            {
                float.TryParse(evt.param, out var timeScale);
                float.TryParse(evt.param2, out var startTime);
                float.TryParse(evt.param3, out var duration);
                float.TryParse(evt.param4, out var endTime);
                //BattleDebug.LogError("时间缩放 " + timeScale + " " + duration);
                StageManager.Instance.ChangeTimeScale(timeScale,duration,startTime,endTime);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.ChangeCameraFollow)
        {
            if (needStart)
            {
                var v3 = evt.param.Split(';');
                if (v3.Length == 3)
                {
                    float.TryParse(v3[0], out var x);
                    float.TryParse(v3[1], out var y);
                    float.TryParse(v3[2], out var z);
                    //BattleDebug.LogError("改变相机跟随 " + x + " " + y + " " + z);
                    float.TryParse(evt.param2, out var startTime);
                    float.TryParse(evt.param3, out var holdTime);
                    float.TryParse(evt.param4, out var endTime);
                    CameraManager.Instance.ChangeCameraFollow(new Vector3(x,y,z),startTime,holdTime,endTime);
                }
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.ChangeCameraTrack)
        {
            if (needStart)
            {
                var v3 = evt.param.Split(';');
                if (v3.Length == 3)
                {
                    float.TryParse(v3[0], out var x);
                    float.TryParse(v3[1], out var y);
                    float.TryParse(v3[2], out var z);
                    //BattleDebug.LogError("改变相机跟踪 " + x + " " + y + " " + z);
                    float.TryParse(evt.param2, out var startTime);
                    float.TryParse(evt.param3, out var holdTime);
                    float.TryParse(evt.param4, out var endTime);
                    CameraManager.Instance.ChangeCameraTrack(new Vector3(x,y,z),startTime,holdTime,endTime);
                }
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.ShowHud)
        {
            if (needStart)
            {
                StageManager.Instance.TeamGroup.ShowInteractingHud(BattleConfigManager.GetLangText(evt.param));
            }
            else if (needEnd)
            {
                StageManager.Instance.TeamGroup.HideInteractingHud();
            }

            if (interactableState[i] == 1)
            {
                var restTime = startTime + evt.endTime - TimeManager.time;
                var totalTime = evt.endTime - evt.startTime;
                StageManager.Instance.TeamGroup.UpdateInteractingHud(restTime,totalTime);
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.ShowBubble)
        {
            if (needStart)
            {
                int.TryParse(evt.param2, out var teamIndex);
                int.TryParse(evt.param3, out var unitIndex);
                int.TryParse(evt.param4, out var type);
                var unit = UnitManager.Instance.GetUnitByTeamAndIndex(teamIndex, unitIndex);
                if (unit != null)
                {
                    unit.ShowChatBubble(BattleConfigManager.GetLangText(evt.param),type);
                }
            }

            if (needEnd)
            {
                int.TryParse(evt.param2, out var teamIndex);
                int.TryParse(evt.param3, out var unitIndex);
                int.TryParse(evt.param4, out var type);
                var unit = UnitManager.Instance.GetUnitByTeamAndIndex(teamIndex, unitIndex);
                if (unit != null)
                {
                    unit.HideChatBubble();
                }
            }
        }
        else if (evt.eventType == EBattleInteractableEvent.JoinTeam)
        {
            if (needStart)
            {
                int.TryParse(evt.param, out var teamIndex);
                int.TryParse(evt.param2, out var unitIndex);
                var unit = UnitManager.Instance.GetUnitByTeamAndIndex(teamIndex, unitIndex);
                if (unit != null)
                {
                    UnitManager.Instance.JoinTeam(unit);
                }
            }
        }
    }

    public bool IsInteracting()
    {
        return startTime >= 0 && !finished;
    }
}
